package fr.univnantes.alma;

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;

import fr.alma.tpBank.TpBankPackage;

public class Exercice {

	public static void main(String[] args) {

		Resource resourceModel = loadModel(new File("../../workspace/Banque/model/Prioritaire.banque"));
		displayResource(resourceModel);
		addSuffixAttributeName(resourceModel);
		displayResource(resourceModel);
		//saveResource(resourceModel);
		
	}
	
	/**
	 * Chargement du modele
	 * */
	public static Resource loadModel(File model){
		
		 ResourceSet resourceSet = new ResourceSetImpl();

         resourceSet.getPackageRegistry().put(TpBankPackage.eNS_URI,
        		 TpBankPackage.eINSTANCE);

         Map<String, Object> extensionToFactoryMap =
        		 resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap();
         extensionToFactoryMap.put("banque", new XMIResourceFactoryImpl());

         URI uri = URI.createFileURI(model.getAbsolutePath());

         Resource resource = resourceSet.getResource(uri, true);

         return resource;
	}
	
	/**
	 * Affichage de la ressource
	 * */
	public static void displayResource(Resource resource){
		System.out.println("\n---Affichage de la ressource---");
		System.out.println("*******");
		for(EObject container : resource.getContents()){
			
			System.out.println("Conteneur (" + container.eClass().getName() + ") : " + findEAttributeValue(container, "name"));
			findChildsAndDisplay(container, 0);
		}
		System.out.println("*******");
	}
	
	/**
	 * Sauvegarde de la ressource
	 * */
	private static void saveResource(Resource resourceModel){
		try {
			resourceModel.save(Collections.EMPTY_MAP);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Affichage des fils
	 * */
	private static void findChildsAndDisplay(EObject container, Integer niveau){
		for (EObject childContainer : container.eContents()){
			System.out.println("Fils (Niveau " + niveau + " : " + childContainer.eClass().getName() + ") : "
					+ findEAttributeValue(childContainer, "name"));
			if (container.eContainmentFeature() != null){
				System.out.println("\t\tNom de la référence de contenance \n " +
						"\t\tdu parent (" + container.eClass().getName() 
						+ ") référençant\n" +
						"\t\tl'EObject courant ("+
						childContainer.eClass().getName()+") : " + 
						childContainer.eContainingFeature().getName());
			}
			if (childContainer.eContents().size() > 0){
				niveau ++;
				findChildsAndDisplay(childContainer, niveau);
			}
		}
	}
	
	/**
	 * Obtention de la valeur de l attribut souhaite
	 * */
	private static String findEAttributeValue(EObject object, String attributeName){
		for(EAttribute attr : object.eClass().getEAllAttributes()){
			if (attr.getName().equals(attributeName)){
				return object.eGet(attr).toString();
			}
		}
		return null;
	}
	
	/**
	 * Obtention de l attribut souhaite
	 * */
	private static EAttribute findEAttribute(EObject object, String attributeName){
		for(EAttribute attr : object.eClass().getEAllAttributes()){
			if (attr.getName().equals(attributeName)){
				return attr;
			}
		}
		return null;
	}
	
	/**
	 * Ajout d un suffixe aux attributs de tous les EObjects
	 * Defaut : 'SUFFIX_'
	 * */
	private static void addSuffixAttributeName(Resource resourceModel){
		System.out.println("\n***Modification de la ressource***");
		for(EObject eObject : resourceModel.getContents()){
			AddSuffixChildAttribute(eObject);
		}
	}
	
	private static void AddSuffixChildAttribute(EObject eObject){		
		for (EObject child : eObject.eContents()){
			String name = findEAttributeValue(child, "name");
			EAttribute attr = findEAttribute(child, "name");
			if (name != null){
				name = "SUFFIX_" + name;				
				child.eSet(attr, name);
			}			
			if (child.eContents().size() > 0){
				AddSuffixChildAttribute(child);
			}
		}
	}
	
}
